﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Dia2Lib;

namespace Kokomo.Mirror.PeFormat.Symbols
{
	public sealed class SymbolProvider
	{
		public static readonly string InternetSymbolStoreUrl = "http://msdl.microsoft.com/download/symbols";
		public static readonly string InternetSourceStoreUrl = "http://referencesource.microsoft.com/symbols ";

		static SymbolProvider()
		{
			string defaultSearchString = SymbolProvider.MakeSymbolServerSearchPathString(SymbolProvider.InternetSymbolStoreUrl);
			Default = new SymbolProvider(defaultSearchString);
		}

		public static SymbolProvider Default { get; private set; }

		public static string MakeSymbolServerSearchPathString(
			string symbolServerUrl,
			string localSymbolDirectory = null
			)
		{
			string symbolString = string.Format(".;srv*{0}*{1}",
				localSymbolDirectory,
				symbolServerUrl
				);

			return symbolString;
		}

		public SymbolProvider(
			string symbolSearchPath
			)
		{
			if (string.IsNullOrEmpty(symbolSearchPath)) throw new ArgumentNullException("symbolSearchPath");

			this.SymbolSearchPath = symbolSearchPath;
		}

		public string SymbolSearchPath { get; private set; }

		public SymbolSource LoadSymbolsForModule(string moduleFileName)
		{
			if (moduleFileName == null) throw new ArgumentNullException("moduleFileName");
			IDiaDataSource source = new DiaSourceClass();

			source.loadDataForExe(moduleFileName, this.SymbolSearchPath, null);
			IDiaSession session;
			source.openSession(out session);

			return new SymbolSource(moduleFileName, session);
		}

		public SymbolSource LoadSymbolFile(string symbolFileName)
		{
			if (symbolFileName == null) throw new ArgumentNullException("symbolFileName");

			IDiaDataSource source = new DiaSourceClass();
			source.loadDataFromPdb(symbolFileName);
			IDiaSession session;
			source.openSession(out session);

			return new SymbolSource(symbolFileName, session);
		}
	}
}
